package cn.chenmixuexi.protocol;

import cn.chenmixuexi.message.Message;
import cn.chenmixuexi.protocol.serializer.Serializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
@Slf4j
@ChannelHandler.Sharable
@Component
public class MessageCodecSharable extends MessageToMessageCodec<ByteBuf, Message> {
    @Autowired
    public Serializer serializer;
    @Override
    protected void encode(ChannelHandlerContext ctx, Message msg, List<Object> outlist) throws Exception {
        ByteBuf out = ctx.alloc().buffer();
        out.writeBytes(new byte[]{1,2,3,4});
        //1字节版本
        out.writeByte(1);
        //1字节的序列化方式
        out.writeByte(serializer.getId());
        //1字节的指令类型
        out.writeByte(msg.getMessageType());
        //4字节指令请求序号
        out.writeInt(msg.getSequenceId());
        //1字节对齐填充
        out.writeByte(0xff);

        byte[] bytes = serializer.serialize(msg);

        out.writeInt(bytes.length);
        out.writeBytes(bytes);

        outlist.add(out);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        int magicNum = in.readInt();
        byte version = in.readByte();
        byte serializerType = in.readByte();
        byte messageType = in.readByte();
        int sequenceId = in.readInt();
        in.readByte();
        int length = in.readInt();

        byte[] bytes = new byte[length];
        in.readBytes(bytes, 0, length);

        Message message = null;

        //找到具体类型
        Class<?> messageClass = Message.getMessageClass(messageType);
        log.debug("messageClass:{}",messageClass);
        Object deserialize = serializer.deserialize(messageClass, bytes);

        log.debug("{}, {}, {}, {}, {}, {}", magicNum, version, serializerType, messageType, sequenceId, length);
        log.debug("{}", deserialize);
        out.add(deserialize);
    }
}
